package com.hatch.utils 
{
	import flash.events.SecurityErrorEvent;
	import flash.events.Event;
	import flash.display.Loader;
	import flash.events.IOErrorEvent;
	import flash.system.LoaderContext;
	import flash.system.ApplicationDomain;
	import flash.net.URLRequest;
	import flash.errors.IllegalOperationError;
	import flash.events.EventDispatcher;

	/**
	 * @author ahatch
	 */
	public class RuntimeLibraryItem extends EventDispatcher
	{
		public static const LOAD_COMPLETE:String = 'runtimeItemLoadComplete';
		public static const LOAD_ERROR:String = 'runtimeItemSecurityError';
		
		private var _loader:Loader;
		private var _url:String;

		public function RuntimeLibraryItem(url:String, autoLoad:Boolean = false)
		{
			_url = url;	
			init(autoLoad);
		}

		private function init(loadNow:Boolean = false):void
		{
			_loader = new Loader();
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoadComplete);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
			_loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSecurityError);
			
			if(loadNow)
				load();
		}

		public function load():void
		{
			_loader.load(new URLRequest(_url), new LoaderContext(false, ApplicationDomain.currentDomain));
		}

		public function getClass(className:String):Class
		{
			try
			{
				return _loader.contentLoaderInfo.applicationDomain.getDefinition(className) as Class;
			}
        	catch (e:Error)
			{
				throw new IllegalOperationError(className + " definition not found in " + this);
			}
			return null;
		}

		protected function handleLoadComplete(event:Event):void
		{
			dispatchEvent(new Event(LOAD_COMPLETE, true));
		}

		private function handleIOError(event:IOErrorEvent):void
		{
			dispatchEvent(new Event(LOAD_ERROR, true));
		}

		private function handleSecurityError(e:Event):void 
		{
			dispatchEvent(new Event(LOAD_ERROR, true));
		}

		public function get loader():Loader
		{
			return _loader;
		}

		public function get url():String
		{
			return _url;
		}

		public function set url(value:String):void
		{
			_url = value;
		}
	}
}
